package com.yanqu.road.server.gameplayer.module.activity.witchDraw;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.witchdraw.config.WitchDrawCombConfig;
import com.yanqu.road.entity.activity.witchdraw.config.WitchDrawConfig;

import com.yanqu.road.entity.activity.witchdraw.data.WitchDrawUserData;
import com.yanqu.road.entity.enums.activity.witchdraw.eWitchDrawSummonType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogWitchDrawActivityDraw;
import com.yanqu.road.logic.bussiness.activity.WitchDrawBusiness;
import com.yanqu.road.pb.activity.WitchDrawProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.ActivityMallModule;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.witchdraw.WitchDrawMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

//魔女之夜
public class WitchDrawModule extends GeneralModule {

    private WitchDrawUserData userData;

    public WitchDrawModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = WitchDrawMgr.getActivityInfo();
        if (activityInfo == null){
            return true;
        }
        userData = WitchDrawBusiness.getWitchDrawUserData(activityInfo.getActivityId(), getUserId());
        if (userData == null){
            if (SystemOpenMgr.systemOpen(player, eSystemId.WitchDraw.getValue())){
                initUserData();
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        if (userData != null){
            if (userData.isInsertOption()){
                WitchDrawBusiness.addWitchDrawUserData(userData);
            }else if (userData.isUpdateOption()){
                WitchDrawBusiness.updateWitchDrawUserData(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        if (WitchDrawMgr.getActivityInfo()!=null){
            syncConfig();
            syncUserData();
        }
    }

    public void syncUserData(){
        initUserData();

        if (userData == null){
            return;
        }
        WitchDrawProto.WitchDrawUserDataSync.Builder builder = WitchDrawProto.WitchDrawUserDataSync.newBuilder();
        builder.setUserData(parseUserDataToMsg());
        player.sendPacket(ClientProtocol.U_WITCH_DRAW_SYNC_USER_DATA, builder);
    }

    /**
     * 初始化
     */
    public void initSystem(){
        ActivityInfo activityInfo = WitchDrawMgr.getActivityInfo();
        if (activityInfo == null){
            return;
        }
        syncConfig();
        syncUserData();
    }

    /**
     * 初始化用户数据
     */
    public void initUserData(){
        ActivityInfo activityInfo = WitchDrawMgr.getActivityInfo();
        if (activityInfo == null) {
            return;
        }
        WitchDrawConfig config = WitchDrawMgr.getConfig();
        if (config == null) {
            return;
        }
        if (userData != null && userData.getActivityId() == activityInfo.getActivityId()) {
            return;
        }
        int randomSimpleEnsureTimes = WitchDrawMgr.getRandomSimpleEnsureTimes();
        int randomMythEnsureTimes = WitchDrawMgr.getRandomMythEnsureTimes();
        if (randomSimpleEnsureTimes <= 0 || randomMythEnsureTimes <= 0) {
            log.info("WitchDrawActivity:{} WitchDrawModule initUserData error, randomSimpleEnsureTimes:{}, randomMythEnsureTimes:{}",activityInfo.getActivityId(), randomSimpleEnsureTimes, randomMythEnsureTimes);
            return;
        }
        WitchDrawUserData tmpUserData = new WitchDrawUserData();
        tmpUserData.setActivityId(activityInfo.getActivityId());
        tmpUserData.setUserId(getUserId());
        tmpUserData.setScore(0);
        tmpUserData.setSimpleEnsureTimes(randomSimpleEnsureTimes);
        tmpUserData.setMythEnsureTimes(randomMythEnsureTimes);
        tmpUserData.setTotalDrawTimes(0);
        tmpUserData.setFreeDrawTimes(0);
        tmpUserData.setMythTotalDrawTimes(0);
        tmpUserData.setInsertOption();
        userData = tmpUserData;
    }

    /**
     * 跑测试
     */

    public String test(int people,int perTime){
        WitchDrawConfig config = WitchDrawMgr.getConfig();
        int totalMyth = 0;
        int totalUnxxx = 0;
        for (int num = 0;num<people;num++){
            int drawTimes = 60;
            int mythTime = 0;
            boolean hasMyth = false;
            boolean hasUnxxx = false;
            WitchDrawUserData tmpUserdata = new WitchDrawUserData();
            tmpUserdata.setSimpleEnsureTimes(WitchDrawMgr.getRandomSimpleEnsureTimes());
            tmpUserdata.setMythEnsureTimes(WitchDrawMgr.getRandomMythEnsureTimes());
            Property totalReward = new Property();
            for (int i=0;i<perTime;i++){
                Property singleReward = new Property();
                WitchDrawCombConfig combConfig;
                boolean drawMyth = WitchDrawMgr.canDrawMyth(tmpUserdata);
                if (tmpUserdata.getMythEnsureTimes() == 0 && drawMyth){
                    combConfig = WitchDrawMgr.getMythEnsureCombConfig();
                }else if (tmpUserdata.getSimpleEnsureTimes() == 0){
                    combConfig = WitchDrawMgr.getSimpleEnsureCombConfig();
                }else {
                    //返回随机抽取
                    combConfig = WitchDrawMgr.randomDrawCombConfig(tmpUserdata.getTotalDrawTimes(), drawMyth);
                }

                if (combConfig.getType() == eWitchDrawSummonType.mythical.getValue()) {
                    //设为-1 表示已经使用过神话保底次数
                    tmpUserdata.setMythEnsureTimes(-1);
                    mythTime ++;
                    drawTimes += config.getDrawMythFreeTimes();
                    hasMyth= true;
                    if (tmpUserdata.getSimpleEnsureTimes() > 0){
                        tmpUserdata.setSimpleEnsureTimes(tmpUserdata.getSimpleEnsureTimes() - 1);
                    }
                    tmpUserdata.setFreeDrawTimes(tmpUserdata.getFreeDrawTimes()+config.getDrawMythFreeTimes());
                } else if (combConfig.getType() == eWitchDrawSummonType.unparalleled.getValue()) {
                    //重置无双召唤次数
                    hasUnxxx = true;
                    tmpUserdata.setSimpleEnsureTimes(WitchDrawMgr.getRandomSimpleEnsureTimes());
                    if (tmpUserdata.getMythEnsureTimes() > 0){
                        tmpUserdata.setMythEnsureTimes(tmpUserdata.getMythEnsureTimes() - 1);
                    }

                } else if (combConfig.getType() == eWitchDrawSummonType.legend.getValue()) {
                    if (tmpUserdata.getSimpleEnsureTimes() > 0){
                        tmpUserdata.setSimpleEnsureTimes(tmpUserdata.getSimpleEnsureTimes() - 1);
                    }
                    if (tmpUserdata.getMythEnsureTimes() > 0){
                        tmpUserdata.setMythEnsureTimes(tmpUserdata.getMythEnsureTimes() - 1);
                    }
                }else {
                    if (tmpUserdata.getSimpleEnsureTimes() > 0){
                        tmpUserdata.setSimpleEnsureTimes(tmpUserdata.getSimpleEnsureTimes() - 1);
                    }
                    if (tmpUserdata.getMythEnsureTimes() > 0){
                        tmpUserdata.setMythEnsureTimes(tmpUserdata.getMythEnsureTimes() - 1);
                    }
                }
                tmpUserdata.setTotalDrawTimes(tmpUserdata.getTotalDrawTimes() + 1);
                //先拿出奖励


            }
            if (hasMyth){
                totalMyth++;
            }
            if (hasUnxxx){
                totalUnxxx++;
            }
//            System.out.println("zz 第"+num+"次抽奖结果:");
            //System.out.println("zz "+PropertyHelper.parsePropertyToString(totalReward)+"总共抽了:"+tmpUserdata.getTotalDrawTimes()+"神话次数:"+mythTime);
        }
        String x ="测试人数"+people+"每人抽奖"+perTime+ " 总共神话次数:" + totalMyth + "总共无双次数:" + totalUnxxx;
        System.out.println(x);
        return x;

    }

    /**
     * 开始抽奖
     */
    public int draw(int activityId,int drawTimes){
        if (drawTimes <= 0){
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_DRAW_TIMES_ERROR;
        }
        int check = simpleCheck(activityId);
        if (check != 0){
            return check;
        }

        WitchDrawConfig config = WitchDrawMgr.getConfig();
        int drawItemId = config.getDrawItemId();
        //如果不是单抽 检测一下是否解锁多抽
        if (drawTimes > 1){
            //如果小于总抽数量
            if (userData.getTotalDrawTimes() < config.getTenDrawUnlockParam()){
                return GameErrorCode.E_WITCH_DRAW_ACTIVITY_TEN_DRAW_NO_UNLOCK;
            }
        }
        CurrencyModule currencyModule = player.getModule(CurrencyModule.class);
        Property drawItemProperty = new Property();
        int useFreeDrawTimes = 0;
        if (userData.getFreeDrawTimes() > 0){
            if (drawTimes > userData.getFreeDrawTimes()){
                useFreeDrawTimes = userData.getFreeDrawTimes();
                int costItemNum = drawTimes - useFreeDrawTimes;
                drawItemProperty = new Property(drawItemId, costItemNum);
                if (!currencyModule.currencyIsEnough(drawItemProperty)){
                    return GameErrorCode.E_WITCH_DRAW_ACTIVITY_ITEM_NO_ENOUGH;
                }
                userData.setFreeDrawTimes(0);
                currencyModule.removeCurrency(drawItemProperty, eLogMoneyType.WitchDraw,eLogMoneyType.WitchDrawDrawCost);
            }else {
                useFreeDrawTimes = drawTimes;
                userData.setFreeDrawTimes(userData.getFreeDrawTimes() - drawTimes);
            }
        }else {
            drawItemProperty = new Property(drawItemId, drawTimes);
            if (!currencyModule.currencyIsEnough(drawItemProperty)){
                return GameErrorCode.E_WITCH_DRAW_ACTIVITY_ITEM_NO_ENOUGH;
            }
            currencyModule.removeCurrency(drawItemProperty, eLogMoneyType.WitchDraw,eLogMoneyType.WitchDrawDrawCost);
        }
        List<WitchDrawProto.WitchDrawNoticeData> needUploadList = new ArrayList<>();

        WitchDrawProto.WithDrawDrawResp.Builder resp = WitchDrawProto.WithDrawDrawResp.newBuilder();
        resp.setRet(0);
        for (int i=0;i<drawTimes;i++){
            WitchDrawProto.WitchDrawSingleDrawData.Builder singleDrawData = WitchDrawProto.WitchDrawSingleDrawData.newBuilder();
            boolean needUpload = false;
            Property singleReward = new Property();
            WitchDrawCombConfig randomDrawResult = getRandomDrawResult();
            if (randomDrawResult == null){
                log.error("WitchDrawActivity:{} WitchDrawModule draw time in{} error, randomDrawResult is null,return error",activityId,i);
                return GameErrorCode.E_WITCH_DRAW_ACTIVITY_CONFIG_ERROR;
            }
            if (randomDrawResult.getType() == eWitchDrawSummonType.mythical.getValue()) {
                //设为-1 表示已经使用过神话保底次数
                userData.setMythEnsureTimes(-1);
                //给神话次数加1
                userData.setMythTotalDrawTimes(userData.getMythTotalDrawTimes()+1);
                reduceSimpleEnsureTimes();
                userData.setFreeDrawTimes(userData.getFreeDrawTimes()+config.getDrawMythFreeTimes());
                needUpload = true;
            } else if (randomDrawResult.getType() == eWitchDrawSummonType.unparalleled.getValue()) {
                //重置无双召唤次数
                userData.setSimpleEnsureTimes(WitchDrawMgr.getRandomSimpleEnsureTimes());
                reduceMythEnsureTimes();
                needUpload = true;
            } else if (randomDrawResult.getType() == eWitchDrawSummonType.legend.getValue()) {
                reduceEnsureTimes();
                needUpload = true;
            }else {
                reduceEnsureTimes();
            }
            userData.setTotalDrawTimes(userData.getTotalDrawTimes() + 1);
            //先拿出奖励
            singleReward = PropertyHelper.parseNewStringToProperty(randomDrawResult.getReward());
            //入背包
            currencyModule.addCurrency(singleReward, eLogMoneyType.WitchDraw,eLogMoneyType.WitchDrawDrawGet);
            int drawScore = 0;
            //判断是不是免费
            int isFree = 0;
            if (useFreeDrawTimes > 0){
                isFree = 1;
                useFreeDrawTimes--;
            }else {
                //拿出需要加的积分
                drawScore = config.getDrawScore();
            }
            long oldScore = userData.getScore();
            userData.setScore(oldScore + drawScore);
            //mall积分模块加积分（用于解锁商品购买）
            player.getModule(ActivityMallModule.class).addScore(activityId, config.getScoreItemId(), drawScore);
//            Property scoreReward = new Property(config.getScoreItemId(), drawScore);
//            //入背包
//            currencyModule.addCurrency(scoreReward, eLogMoneyType.WitchDraw,eLogMoneyType.WitchDrawDrawGet);
            //加入返回数据
            singleDrawData.setDrawId(randomDrawResult.getId());
            String value = PropertyHelper.parsePropertyToString(singleReward);
            singleDrawData.setReward(value);
            singleDrawData.setScoreReward(drawScore);
            resp.addDrawData(singleDrawData);


            //加入需要上传的数据
            if (needUpload){
                WitchDrawProto.WitchDrawNoticeData.Builder noticeData = WitchDrawProto.WitchDrawNoticeData.newBuilder();
                noticeData.setActivityId(activityId);
                noticeData.setUserId(getUserId());
                noticeData.setServerId(GameServer.getInstance().getServerId());
                noticeData.setDrawId(randomDrawResult.getId());
                noticeData.setDrawType(randomDrawResult.getType());
                noticeData.setNickName(player.getUserInfo().getNickName());
                noticeData.setReward(value);
                noticeData.setTime(System.currentTimeMillis());
                WitchDrawProto.WitchDrawNoticeData noticeMsg = noticeData.build();
                needUploadList.add(noticeMsg);
            }

            LogWitchDrawActivityDraw log = new LogWitchDrawActivityDraw(activityId,getUserId(),randomDrawResult.getId(),randomDrawResult.getType(),isFree,oldScore,drawScore,userData.getScore(),value,new Date());
            AutoLogMgr.add(log);

        }
        if (!needUploadList.isEmpty()){
            WitchDrawProto.UpdateNoticeDataToCrossReq.Builder updateNoticeDataToCrossReq = WitchDrawProto.UpdateNoticeDataToCrossReq.newBuilder();
            updateNoticeDataToCrossReq.setActivityId(activityId);
            updateNoticeDataToCrossReq.addAllNoticeData(needUploadList);
            player.sendPacket(CrossProtocol.C_CROSS_WITCH_DRAW_UPLOAD_NOTICE,updateNoticeDataToCrossReq);
        }
        boolean needAddScoreRank = true;
        ActivityInfo activityInfo = WitchDrawMgr.getActivityInfo();
        if (ActivityMgr.activityInRewardPeriod(activityInfo)){
            needAddScoreRank = false;
        }

        //更新成就 排行榜
        if (needAddScoreRank){
            player.notifyListener(eGamePlayerEventType.WitchDrawScoreRank.getValue(),userData.getScore());
        }
        player.notifyListener(eGamePlayerEventType.WitchDrawScoreCondition.getValue(),userData.getScore());
        //回包
        resp.setUserData(parseUserDataToMsg());
        player.sendPacket(ClientProtocol.U_WITCH_DRAW_DRAW,resp);

        return 0;

    }

    /**
     * 主动获取玩家数据
     */
    public int getUserData(int activityId){
        int check = simpleCheck(activityId);
        if (check != 0){
            return check;
        }
        WitchDrawProto.WitchDrawGetUserDataResp.Builder resp = WitchDrawProto.WitchDrawGetUserDataResp.newBuilder();
        resp.setRet(0);
        resp.setUserData(parseUserDataToMsg());
        player.sendPacket(ClientProtocol.U_WITCH_DRAW_GET_USER_DATA,resp);
        return 0;
    }

    /**
     * 保底次数减少
     */
    public void reduceEnsureTimes(){
        reduceSimpleEnsureTimes();
        reduceMythEnsureTimes();
    }

    /**
     * 减少神话保底
     */
    public void reduceMythEnsureTimes(){
        if (userData.getMythEnsureTimes() > 0){
            userData.setMythEnsureTimes(userData.getMythEnsureTimes() - 1);
        }
    }

    /**
     * 减少普通保底
     */
    public void reduceSimpleEnsureTimes(){
        if (userData.getSimpleEnsureTimes() > 0){
            userData.setSimpleEnsureTimes(userData.getSimpleEnsureTimes() - 1);
        }
    }





    /**
     * 获取抽奖结果
     */
    public WitchDrawCombConfig getRandomDrawResult(){
        boolean canMyth = WitchDrawMgr.canDrawMyth(userData);
        //如果神话保底次数为0 并且可以出神话
        if (userData.getMythEnsureTimes() == 0 && canMyth){
            WitchDrawCombConfig combConfig = WitchDrawMgr.getMythEnsureCombConfig();
            if (combConfig != null){

                return combConfig;
            }else {
                log.error("WitchDrawActivity:{} WitchDrawModule getRandomDrawResult error, mythEnsureCombConfig is null",userData.getActivityId());
            }
        }
        if (userData.getSimpleEnsureTimes() == 0){
            WitchDrawCombConfig combConfig = WitchDrawMgr.getSimpleEnsureCombConfig();
            if (combConfig != null){
                //重置普通保底次数
                userData.setSimpleEnsureTimes(WitchDrawMgr.getRandomSimpleEnsureTimes());
                return combConfig;
            }else {
                log.error("WitchDrawActivity:{} WitchDrawModule getRandomDrawResult error, simpleEnsureCombConfig is null",userData.getActivityId());
            }
        }
        //返回随机抽取
        WitchDrawCombConfig combConfig = WitchDrawMgr.randomDrawCombConfig(userData.getTotalDrawTimes(),canMyth);

        return combConfig;
    }



    /**
     * 简单检查
     * @param activityId
     * @return
     */
    public int simpleCheck(int activityId) {
        ActivityInfo activityInfo = WitchDrawMgr.getActivityInfo();
        if (activityInfo == null) {
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_NO_OPEN;
        }
        if (activityInfo.getActivityId() != activityId) {
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_ID_ERROR;
        }
        //领奖期也可以玩 但是不加分吧
        if (!ActivityMgr.activityInShowTime(activityInfo)) {
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_NO_IN_TIME;
        }
        if (!SystemOpenMgr.systemOpen(player, eSystemId.WitchDraw.getValue())) {
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_NO_UNLOCK;
        }
        WitchDrawConfig config = WitchDrawMgr.getConfig();
        if (config == null) {
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_CONFIG_ERROR;
        }
        if (userData == null||userData.getActivityId() != activityId) {
            initUserData();
        }
        if (userData == null||userData.getActivityId() != activityId) {
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_NO_OPEN;
        }

        return 0;
    }

    /**
     * 同步一下配置
     */
    public void syncConfig(){
        WitchDrawProto.WitchDrawConfigSync.Builder msg = WitchDrawMgr.getConfigMsg(player.getLanguage());
        if (msg == null){
            return;
        }
        player.sendPacket(ClientProtocol.U_WITCH_DRAW_SYNC_CONFIG,msg);
    }

    /**
     * 玩家数据转化为消息
     * @return
     */

    public WitchDrawProto.WitchDrawUserData.Builder parseUserDataToMsg(){
        if (userData == null){
            return null;
        }
        WitchDrawProto.WitchDrawUserData.Builder builder = WitchDrawProto.WitchDrawUserData.newBuilder();
        builder.setScore(userData.getScore());
        builder.setDrawTimes(userData.getTotalDrawTimes());
        builder.setFreeDrawTimes(userData.getFreeDrawTimes());
        return builder;
    }

    /**
     * 上跨服获取抽奖公告
     */
    public int getNoticeDataFromCross(WitchDrawProto.WitchDrawGetNoticeDataReq req){
        if (req == null){
            return GameErrorCode.E_WITCH_DRAW_ACTIVITY_ID_ERROR;
        }
        int check = simpleCheck(req.getActivityId());
        if (check != 0){
            return check;
        }
        player.sendPacket(CrossProtocol.C_CROSS_WITCH_DRAW_GET_ALL_NOTICE,req.toBuilder());
        return 0;
    }


}
